﻿using AppFlat.Domain.IRespostroy;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace AppFlat.Domain.Respostory
{
    public class BaseRepostory<T>  where T :class
    {
        public DbContext Db
        {
            get
            {
                return DbContextFactory.Create();
            }
        }
        


        public void Add(T model)
        {
            Db.Set<T>().Add(model);
        }

        public void Delete(T model)
        {
            Db.Entry<T>(model).State = EntityState.Deleted;
        }

        public IQueryable<T> GetEntities(Expression<Func<T, bool>> whereLambda)
        {
            IQueryable<T> query = Db.Set<T>().AsNoTracking();
            if (whereLambda != null)
                query = query.Where(whereLambda);
            return query;
        }

        public IQueryable<T> GetEntities<OrderField>(int pageIndex, int pageSize, out int total, Expression<Func<T, bool>> whereLambda, Expression<Func<T, OrderField>> orderBy, bool isAsc)
        {
            IQueryable<T> query = Db.Set<T>().AsNoTracking();
            if (whereLambda != null)
                query = query.Where(whereLambda);

            total = query.Count();

            if (isAsc)
            {
                query = query.OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            else
            {
                query = query.OrderByDescending(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            return query;
        }

        public async Task<T> GetEntityAsync(Expression<Func<T, bool>> whereLambda)
        {
            return await Db.Set<T>().AsNoTracking().FirstOrDefaultAsync(whereLambda);
        }

        public void Update(T model)
        {
            Db.Entry<T>(model).State = EntityState.Modified;
        }

        public void Update(T model, params string[] updateFields)
        {
           //Db.Set<T>().Attach(model);
            Db.Entry<T>(model).State = EntityState.Unchanged;

            // model的所有属性
            foreach(var prop in typeof(T).GetProperties())
            {
                if ( updateFields.Contains(prop.Name))
                {
                    Db.Entry<T>(model).Property(prop.Name).IsModified = true;
                }
            }

        }

        public int ExecuteNonQuery(string sql, SqlParameter[] sp)
        {
            return  Db.Database.ExecuteSqlCommand(sql, sp);
        }
    }
}
